const gameId = 10004
const gameName = "Wild Bandito"
const gamType = "slot"
const WebSocket = require('ws');
const express = require('express');
const port_config = require('../../util/port_config');
const { user } = require('../../util/mysql_config');
// const redis = require('../../dao/redis');
const dao = require('../../dao/dao');
const dao_game = require('../../dao/dao_game');
const game_config = require('./gameConfig');
const game_public = require('../game_public');  // 游戏公共方法
const is_debug = false;

let total_bet = 0;
let total_win = 0;
let rtp = 0;
let gameLevel = 0;

const app = express();
const port = port_config.game_wldd;

// 创建 WebSocket 服务器
const wss = new WebSocket.Server({ noServer: true });

// 创建 clients Map 来存储所有连接的客户端
const clients_wldd = new Map();

// 启动定时器，自动保存数据到数据库  用户金币数据
// startAutoSaveToDatabase();

// 处理 WebSocket 连接
wss.on('connection', (ws) => {

    ws.on('message', async (message) => {
        try {
            const data = JSON.parse(message);
            if (data.action === 'clientId') {  // 处理客户端 ID
                // 设置 clientId
                const clientId = data.playerId;
                clients_wldd.set(clientId, ws);
                console.log(`玩家 ${clientId} 进入亡灵大盗游戏`);
            } else if (data.action === 'spin') { // 处理用户旋转
                userSpin(data, ws);
            } else if (data.action === 'test') {
                const clientId = data.playerId;
                clients_wldd.set(clientId, ws);
                console.log(`测试玩家 ${clientId} 进入亡灵大盗游戏`);
            }
        } catch (error) {
            console.error('消息处理错误:', error);
            ws.send(JSON.stringify({
                action: 'error',
                message: '消息处理错误'
            }));
        }
    });

    ws.on('error', (error) => {
        console.error('WebSocket error:', error);
    });

    ws.on('close', () => {
        console.log('客户端断开连接');
        for (const [clientId, clientWs] of clients_wldd) {
            if (clientWs === ws) {
                clients_wldd.delete(clientId);
                console.log(`玩家 ${clientId} 退出亡灵大盗游戏`);
                break;
            }
        }
        console.log(`当前亡灵大盗的在线玩家数量: ${clients_wldd.size}`);
    });
});

// 设置 HTTP 服务
app.server = app.listen(port, async () => {
    console.log(`✅亡灵大盗服务器启动成功，端口： ${port}`);

    try {
        let ret = await dao_game.getGameLevel(gameId);
        if (ret.success) {
            gameLevel = parseFloat(ret.data.level);
        } else {
            console.log('获取亡灵大盗水位失败:', error);
            app.server.close();
            wss.close();
        }
    } catch (error) {
        console.log('获取亡灵大盗水位失败:', error);
        app.server.close();
        wss.close();
    }
});

// 使 WebSocket 和 HTTP 服务共用同一个端口
app.server.on('upgrade', (request, socket, head) => {
    wss.handleUpgrade(request, socket, head, (ws) => {
        wss.emit('connection', ws, request);
    });
});


//旋转  ※重点
async function userSpin(data, ws) {

    const is_debug = data.is_debug;
    let respCode = ""

    let bet = data.bet;
    let betLevel = data.betLevel;
    let playerId = data.playerId;

    let RTP = 0;
    let RTPmin = 0;   // 最小RTP
    let isFree = 0;
    let isMustWin = false;


    if (!is_debug) {
        let RTPData = await game_public.getPlayerRTP(playerId);
        if (RTPData.respCode === 'SUCCESS') {
            RTP = RTPData.RTP;
            RTPmin = RTPData.RTPmin;
            isFree = RTPData.isFree;
            isMustWin = RTPData.isMustWin;
        } else {
            ws.send(false)
            return;
        }
    } else {
        RTP = data.rtp / 100;
        RTPmin = data.RTPmin
        isFree = data.isFree;
    }

    let maxRTP = 0.98;
    if (isFree) {
        maxRTP = 0.95;
    }

    RTP = parseFloat(RTP);

    let tryCount = 0;
    let maxTries = 3;
    // 抽符号直到满足条件
    let symbol, symbol_old, winscore = 0, winLineArr = [], win = 0;
    do {
        symbol = getSymbolRandom();       // 获取随机符号
        symbol_old = [...symbol];         // 复制数组
        let ret = checkWinScore(symbol, betLevel);
        winscore = ret[0];                // 获取中奖分数
        winLineArr = ret[1];              // 获取中奖行
        win = winscore - bet;             // 计算输赢

        tryCount++;

    } while (
        (
            isMustWin && (winscore < 500 || winscore > 1000) // 如果必须中奖且未中奖，则继续循环
        )
        || (
            (RTP < RTPmin && winscore === 0) ||  // RTP 低时，必须中奖
            (RTP >= maxRTP && winscore > 0)           // RTP 高时，不能中奖
        )
        && tryCount < maxTries
    );


    let newCoin = 0;

    if (!is_debug) {  //正式模式下才过数据库
        let req = await dao_game.updatePlayerCoinAndBetRecord(playerId, win, bet, winscore, isFree)
        if (req.respCode == "SUCCESS") {
            newCoin = req.coin;
        }
    }

    let spinResData = JSON.stringify({
        action: 'spinResponse',
        Symbol: symbol_old,
        winscore: winscore,
        winLineArr: winLineArr,
        bet: bet,
        win: win,
        newCoin: newCoin,
    })
    ws.send(spinResData);  //发送数据给客户端

    // setTimeout(() => {
    //     ws.send(spinResData);  // 延迟 2 秒后发送数据给客户端
    // }, 5000);


    //把投注数据存在数据库  debug模式下不保存
    if (!is_debug) {
        await dao_game.insertBetData(bet, winscore, win, gameId, gameName, gamType, playerId);
    }
}

//获取随机的符号
function getSymbolRandom() {
    let symbol;
    while (true) {
        symbol = [];
        for (let i = 0; i < 15; i++) {
            let randomNum = Math.random();
            let prob = 0.63;   //0.5--39%   0.59--66%   0.6--72%  0.61--78%   0.62--82%   0.63--87%   0.65--95%   0.66--105%  0.67--108%  0.7--132%
            let random;
            if (randomNum < prob) {
                let highNumbers = [7, 8, 9];
                random = highNumbers[Math.floor(Math.random() * highNumbers.length)];
            } else {
                random = Math.floor(Math.random() * 7);
            }
            symbol.push(random);
        }

        // 检查第1、6、11个元素是否相同
        if (!(symbol[0] === symbol[5] && symbol[0] === symbol[10])) {
            break;
        }
        // console.log("符号数组不匹配，重新生成...",symbol);

    }
    return symbol;
}

//检查输赢
function checkWinScore(symbol, betLevel) {
    symbol = handleThreeSame(symbol);

    let winLineArr = [];
    for (let i = 0; i < game_config.winLine.length; i++) {
        let winLine = game_config.winLine[i];
        let sym1 = symbol[winLine[0] - 1];
        let sym2 = symbol[winLine[1] - 1];
        let sym3 = symbol[winLine[2] - 1];
        let sym4 = symbol[winLine[3] - 1];
        let sym5 = symbol[winLine[4] - 1];
        let winNum = checkWinNum(sym1, sym2, sym3, sym4, sym5);
        winLine = winLine.slice(0, winNum);
        if ((winNum >= 3 || (winNum == 2 && (sym1 == 7 || sym1 == 8 || sym1 == 9)))) {
            winLineArr.push(winLine);
        }
    }
    winLineArr = filterContainedAndDuplicateSubarrays(winLineArr);
    let winscore = 0;
    winscore = jiSuanWinScore(winLineArr, symbol);
    winscore = winscore * betLevel;
    // for (let i = 0; i < symbol.length; i++) {
    //     if (symbol[i] == 11) {
    //         console.log("符号：",symbol);
    //         console.log("赢钱：",winscore);
    //     }
    // }
    return [winscore, winLineArr];
}

//处理wild
function handleThreeSame(symbol) {
    for (let i = 0; i < 5; i++) {
        if (symbol[i] == symbol[i + 5] && symbol[i + 5] == symbol[i + 10]) {
            symbol[i] = 11;
            symbol[i + 5] = 11;
            symbol[i + 10] = 11;
        }
    }
    return symbol;
}

// 检查有几个一样的
function checkWinNum(sym1, sym2, sym3, sym4, sym5) {
    const symbols = [sym1, sym2, sym3, sym4, sym5];
    let count = 1;
    for (let i = 1; i < symbols.length; i++) {
        if (symbols[i] === symbols[0] || symbols[i] === 11) {
            count++;
        } else {
            break;
        }
    }
    return count >= 2 ? count : 0;
}


// 计算最终的winscore
function jiSuanWinScore(winLineArr, symbol) {
    let winscore = 0;
    for (let i = 0; i < winLineArr.length; i++) {
        let targetArr = winLineArr[i];
        let sym = targetArr[0];
        let num = symbol[sym - 1];
        if (num == 7 || num == 8 || num == 9 || num == 10) {
            winscore += game_config.winScore[num][targetArr.length - 2]
        } else {
            winscore += game_config.winScore[num][targetArr.length - 3]
        }
    }
    return winscore;
}

// 过滤掉被包含的子数组
function filterContainedAndDuplicateSubarrays(arr) {
    const seen = new Set();

    // 判断 a 是否被 b 包含（不考虑重复数量，只看元素）
    function isContained(a, b) {
        return a.every(item => b.includes(item));
    }

    return arr.filter((subArr, i) => {
        const sortedStr = [...subArr].sort((a, b) => a - b).join(',');

        // 如果是重复的，跳过
        if (seen.has(sortedStr)) return false;

        // 是否有“比我长的数组”包含我？
        for (let j = 0; j < arr.length; j++) {
            if (i === j) continue;

            const other = arr[j];

            if (
                isContained(subArr, other) &&
                other.length > subArr.length // 👈 只考虑“严格更长”的
            ) {
                return false; // 被更长的包含，移除
            }
        }

        seen.add(sortedStr);
        return true;
    });
}

//改变游戏水位
function changeGameLevel(params) {
    gameLevel = params
}

module.exports = {
    gameId,
    changeGameLevel
};

